﻿#include "RpcBroadcastChannel.h"
#include "XyNet/Channel/RpcSocketChannel.h"
#include "XyNet/Channel/RpcSocketChannelManager.h"
#include "XyNet/Protocol/cpp/Rpc.pb.h"
#include "XyNet/Service/RpcArgument.h"
#include "XyNet/Service/RpcCallback.h"
#include "XyNet/Service/RpcMethod.h"

namespace XyNet
{
	RpcBroadcastChannel::RpcBroadcastChannel(RpcSocketChannelManager* socketChannelManager)
		: _socketChannelManager(socketChannelManager) {}

	RpcBroadcastChannel::~RpcBroadcastChannel() {}

	void RpcBroadcastChannel::setBroadcastAllUsers()
	{
		_broadcastType = AllUsers;
		_specifiedUserIds.clear();	// 清空指定用户
	}

	void RpcBroadcastChannel::setBroadcastLoginUsers()
	{
		_broadcastType = LoginUsers;
		_specifiedUserIds.clear();
	}

	void RpcBroadcastChannel::setBroadcastSpecifiedUser(const Id& userId)
	{
		_broadcastType = SpecifiedUsers;
		_specifiedUserIds.clear();
		_specifiedUserIds.emplace_back(userId);
	}

	void RpcBroadcastChannel::setBroadcastSpecifiedUsers(const vector<Id>& userIds)
	{
		_broadcastType = SpecifiedUsers;
		_specifiedUserIds = userIds;
	}

	shared_ptr<RpcMessage> RpcBroadcastChannel::createMessage(
		RpcMethod* method, shared_ptr<const RpcArgument> argument)
	{
		auto message = make_shared<RpcMessage>();
		auto request = message->mutable_request();
		request->set_data(const_pointer_cast<google::protobuf::Message>(
			argument->getRequest())->SerializeAsString());
		request->set_service_id(method->getServiceId());
		request->set_method_id(method->getId());
		return message;
	}

	vector<shared_ptr<RpcSocketChannel>> RpcBroadcastChannel::makeBroadcastSocketChannels()
	{
		//switch (_broadcastType)
		//{
		//case AllUsers:
		//	return _socketChannelManager->getSocketChannels();
		//	break;
		//case LoginUsers:
		//	return _socketChannelManager->getLoginSocketChannels();
		//	break;
		//case SpecifiedUsers:
		//	return _socketChannelManager->findLoginSocketChannels(&_specifiedUserIds);
		//	break;
		//default:
		//	assert(false);
		//}
		return decltype(makeBroadcastSocketChannels())();
	}

	void RpcBroadcastChannel::callMethod(RpcMethod* method, shared_ptr<RpcCallback> callback)
	{
		//sendData(createMessage(method, callback->getArgument())->SerializeAsString());

		for (auto channel : makeBroadcastSocketChannels())
			channel->callMethod(method, callback->clone());
	}

	//void RpcBroadcastChannel::sendData(const Bytes& data)
	//{
	//	// 遍历连接通道并发送消息
	//	for (auto channel : makeBroadcastSocketChannels())
	//		channel->sendData(data);
	//}
}